In [ ]:
from sklearn.feature_extraction.text import TfidfTransformer, CountVectorizer, TfidfVectorizer
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
from gensim.summarization import summarize
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from nltk.corpus import stopwords
import numpy as np
import numpy.linalg as LA
from nltk.tokenize import sent_tokenize
import os
import nltk
import re
import sys
from nltk import NaiveBayesClassifier
import nltk.classify
from nltk.tokenize import wordpunct_tokenize
from nltk.corpus import stopwords
import re
from nltk.tokenize import RegexpTokenizer
from nltk.stem.snowball import RussianStemmer
from nltk.stem.snowball import SnowballStemmer
from gensim.summarization import keywords
import warnings
warnings.filterwarnings(action='ignore', category=UserWarning, module='gensim')
In [ ]:
df_ans = pd.read_csv("feedbacks_tags.csv", sep='\t')
In [ ]:
df_ans.head()
In [ ]:
mob_comment = pd.Series(df_ans['name'].tolist()).astype(str)
dist_train = mob_comment.apply(len)
dist_train = dist_train[dist_train>10]
pal = sns.color_palette()
plt.figure(figsize=(10, 5))
plt.hist(dist_train, bins=35, range=[0, 35], normed=True)
plt.title('Normalised histogram of character count in questions', fontsize=15)
plt.legend()
plt.xlabel('Number of characters', fontsize=15)
plt.ylabel('Probability', fontsize=15)
In [ ]:
dist_train = mob_comment.apply(lambda x: len(x.split(' ')))
dist_train = dist_train[dist_train>3]
plt.figure(figsize=(10, 5))
plt.hist(dist_train, bins=16, range=[1, 6], color=pal[2], normed=True, label='train')
plt.title('Normalised histogram of word count', fontsize=15)
plt.legend()
plt.xlabel('Number of words', fontsize=15)
plt.ylabel('Probability', fontsize=15)
In [ ]:
from wordcloud import WordCloud
cloud = WordCloud(width=1440, height=1080).generate(" ".join(mob_comment.astype(str)))
plt.figure(figsize=(15, 10))
plt.imshow(cloud)
plt.axis('off')
In [ ]:
stopWords = nltk.corpus.stopwords.words('russian')
In [ ]:
stopWords.append('все')
stopWords.append('очень')
stopWords.append('это')
stopWords.append('все')
stopWords.append('всем')
In [ ]:
mob_comment = df_ans[['count', 'name']]
In [ ]:
mob_comment.mobile_app_comment = mob_comment.name.str.lower()
In [ ]:
mob_comment.name.str.split(expand=True).stack().value_counts()[:10]
In [ ]:
tokenizer = nltk.word_tokenize
In [ ]:
mob_comment.mobile_app_comment = mob_comment.mobile_app_comment.str.replace(',', ' ')
mob_comment.mobile_app_comment = mob_comment.mobile_app_comment.str.replace('.', ' ')
mob_comment.mobile_app_comment = mob_comment.mobile_app_comment.str.replace('!', ' ')
In [ ]:
mob_comment['name'] = mob_comment['name'].apply(lambda x: ' '.join([word for word in x.split() if word not in (stopWords)]))
In [ ]:
mob_comment.name.str.split(expand=True).stack().value_counts()[:40]
In [ ]:
stemmer = SnowballStemmer("russian")
def tokenize_and_stem(text):
# сначала токенизируем по предложению, потом по словам, чтобы сохранить "особые" слова
tokens = [word for sent in nltk.sent_tokenize(text) for word in nltk.word_tokenize(sent)]
filtered_tokens = []
# удалим все самое плохое, знаки препинания
for token in tokens:
if re.search('[a-zA-Z0-9А-Яа-я]', token):
filtered_tokens.append(token)
stems = [stemmer.stem(t) for t in filtered_tokens]
return stems
def tokenize_only(text):
tokens = [word.lower() for sent in nltk.sent_tokenize(text) for word in nltk.word_tokenize(sent)]
filtered_tokens = []
for token in tokens:
if re.search('[a-zA-Z0-9А-Яа-я]', token):
filtered_tokens.append(token)
return filtered_tokens
In [ ]:
totalvocab_stemmed = []
totalvocab_tokenized = []
for i in mob_comment.mobile_app_comment:
allwords_stemmed = tokenize_and_stem(i)
totalvocab_stemmed.extend(allwords_stemmed)
allwords_tokenized = tokenize_only(i)
totalvocab_tokenized.extend(allwords_tokenized)
In [ ]:
vocab_frame = pd.DataFrame({'words': totalvocab_tokenized}, index = totalvocab_stemmed)
print ('Всего ' + str(vocab_frame.shape[0]) + ' слов в словаре')
In [ ]:
tfidf_vectorizer = TfidfVectorizer( max_features=20000, min_df=1, max_df=0.99,
use_idf=True, tokenizer=tokenize_and_stem, ngram_range=(1,5))
tfidf_matrix = tfidf_vectorizer.fit_transform(mob_comment.name)
print(tfidf_matrix.shape)
print(mob_comment['count'].shape)
In [ ]:
#mob_comment = mob_comment.reset_index()
In [ ]:
from sklearn.metrics.pairwise import cosine_similarity
dist = 1 - cosine_similarity(tfidf_matrix)
In [ ]:
# тут не работает
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
range_n_clusters = [ 2 , 5, 7 , 10, 15] # clusters range you want to select
best_clusters = 0
previous_silh_avg = 0.0
for n_clusters in range_n_clusters:
clusterer = KMeans(n_clusters=n_clusters)
cluster_labels = clusterer.fit_predict(tfidf_matrix)
silhouette_avg = silhouette_score(tfidf_matrix, cluster_labels)
print (silhouette_avg)
if silhouette_avg > previous_silh_avg:
previous_silh_avg = silhouette_avg
best_clusters = n_clusters
print (best_clusters)
# Final Kmeans for best_clusters
In [ ]:
from sklearn.cluster import KMeans
num_clusters = 5
km = KMeans(n_clusters=num_clusters)
%time km.fit(tfidf_matrix)
clusters = km.labels_.tolist()
In [ ]:
from sklearn.externals import joblib
joblib.dump(km, 'doc_cluster.pkl')
#km = joblib.load('doc_cluster.pkl')
clusters = km.labels_.tolist()
In [ ]:
comments = {'np': list(mob_comment['count']), 'comment': list(mob_comment.name), 'cluster': clusters}
#frame = pd.DataFrame(films, index = [clusters] , columns = ['rank', 'cluster'])
frame = pd.DataFrame(comments)
In [ ]:
frame['cluster'].value_counts()
In [ ]:
grouped = frame['np'].groupby(frame['cluster']) #groupby cluster for aggregation purposes
grouped.mean()
In [ ]:
terms = tfidf_vectorizer.get_feature_names()
In [ ]:
#отсортирует комментарии по близости к кластеру
order_centroids = km.cluster_centers_.argsort()[:, ::-1]
for i in range(num_clusters):
print("Кластер %d:" % i, end='')
cust_word = list()
for ind in order_centroids[i, :8]: #replace 6 with n words per cluster
cust_word.append(vocab_frame.loc[terms[ind].split(' ')].values.tolist()[0][0])
print(set(cust_word))
print()
In [ ]:
from scipy.cluster.hierarchy import ward, dendrogram
linkage_matrix = ward(dist) #define the linkage_matrix using ward clustering pre-computed distances
fig, ax = plt.subplots(figsize=(30, 150)) # set size
ax = dendrogram(linkage_matrix, orientation="right", labels=list(frame.comment));
plt.tick_params(\
axis= 'x', # changes apply to the x-axis
which='both', # both major and minor ticks are affected
bottom='off', # ticks along the bottom edge are off
top='off', # ticks along the top edge are off
labelbottom='off')
plt.tight_layout() #show plot with tight layout
#uncomment below to save figure
plt.savefig('ward_clusters.png', dpi=200) #save figure as ward_clusters
In [ ]:
import string
def strip_proppers(text):
# first tokenize by sentence, then by word to ensure that punctuation is caught as it's own token
tokens = [word for sent in nltk.sent_tokenize(text) for word in nltk.word_tokenize(sent) if word.islower()]
return "".join([" "+i if not i.startswith("'") and i not in string.punctuation else i for i in tokens]).strip()
In [ ]:
def tokenize_and_stem(text):
# сначала токенизируем по предложению, потом по словам, чтобы сохранить "особые" слова
tokens = [word for sent in nltk.sent_tokenize(text) for word in nltk.word_tokenize(sent)]
filtered_tokens = []
# удалим все самое плохое, знаки препинания
for token in tokens:
if re.search('[a-zA-Z0-9А-Яа-я]', token):
filtered_tokens.append(token)
stems = [stemmer.stem(t) for t in filtered_tokens]
return stems
def tokenize_only(text):
tokens = [word.lower() for sent in nltk.sent_tokenize(text) for word in nltk.word_tokenize(sent)]
filtered_tokens = []
for token in tokens:
if re.search('[a-zA-Z0-9А-Яа-я]', token):
filtered_tokens.append(token)
return filtered_tokens
In [ ]:
from gensim import corpora, models, similarities
%time preprocess = [strip_proppers(doc) for doc in mob_comment.mobile_app_comment]
#tokenize
%time tokenized_text = [tokenize_and_stem(text) for text in preprocess]
#remove stop words
%time texts = tokenized_text #[[word for word in text if word not in stopwords] for text in tokenized_text]
In [ ]:
from gensim.corpora import Dictionary
# to create the bigrams
bigram_model = Phrases(texts)
import codecs
if 1 == 1:
with codecs.open('bigram_sentences_all.txt', 'w', encoding='utf_8') as f:
for unigram_sentence in texts:
bigram_sentence = u' '.join(bigram_model[unigram_sentence])
f.write(bigram_sentence + '\n')
from gensim.models.word2vec import LineSentence
bigram_sentences = LineSentence('bigram_sentences_all.txt')
trigram_model = Phrases(bigram_sentences)
triram_sentences = []
for bigram_sentence in bigram_sentences:
triram_sentence = u' '.join(trigram_model[bigram_sentence])
triram_sentences.append(triram_sentence)
#dictionary = Dictionary(texts)
In [ ]:
triram_sentences
In [ ]:
tokenized_text = [tokenize_only(text) for text in triram_sentences]
In [ ]:
dictionary = Dictionary(tokenized_text)
dictionary.filter_extremes(no_below=2, no_above=0.95)
corpus = [dictionary.doc2bow(doc) for doc in tokenized_text]
print('Number of unique tokens: %d' % len(dictionary))
print('Number of documents: %d' % len(corpus))
In [ ]:
num_topics_now = 6
In [ ]:
%time lda = models.LdaModel(corpus, num_topics = num_topics_now, id2word=dictionary,\
random_state = 1024, \
update_every=5, \
chunksize=10000, \
passes=100)\
In [ ]:
lda.show_topics()
In [ ]:
topics_matrix = lda.show_topics(formatted=False, num_words=20)
#topic_words = topics_matrix[:,:,1]
topic_num = 0
for i in range(0,num_topics):
print('Топик №', i, end = ': ')
for k in range(0,10):
print(topics_matrix[i][1][k][0], end=', ')
print()
topic_num +=1
In [ ]:
lda.save('lda_simple_aproach.bin')
In [ ]:
temp = df_ans[['np_answer', 'mobile_app_comment']][df_ans.mobile_app_comment.isnull() == False]
list(temp.iloc[[14]].mobile_app_comment)
In [ ]:
doc = dictionary.doc2bow(texts[14])
doc_lda = lda.get_document_topics(doc)
doc_lda
In [ ]:
top_topics = lda.top_topics(corpus, topn=20)
# Average topic coherence is the sum of topic coherences of all topics, divided by the number of topics.
avg_topic_coherence = sum([t[1] for t in top_topics]) / num_topics
print('Average topic coherence: %.4f.' % avg_topic_coherence)
In [ ]:
import pyLDAvis.gensim
pyLDAvis.enable_notebook()
pyLDAvis.gensim.prepare(lda, corpus, dictionary)
In [ ]:
trigtam_sen = pd.concat([trigram_sen, df], axis=1)
trigtam_sen = trigtam_sen[trigram_sen.sentences.str.strip().str.len() != 0]
In [ ]:
text = 'Доказа́тельство с нулевы́м разглаше́нием (информа́ции) в криптографии (англ. Zero-knowledge proof) — \
интерактивный криптографический протокол, позволяющий одной из взаимодействующих сторон («The verifier» — проверяющей) убедиться \
в достоверности какого-либо утверждения (обычно математического), не имея при этом никакой другой информации от второй стороны \
(«The prover» — доказывающей). Причём последнее условие является необходимым, так как обычно доказать, \
что сторона обладает определёнными сведениями в большинстве случаев тривиально, если она имеет право просто \
раскрыть информацию. Вся сложность состоит в том, чтобы доказать, что у одной из сторон есть информация, \
не раскрывая её содержание. Протокол должен учитывать, что доказывающий сможет убедить проверяющего только \
в случае, если утверждение действительно доказано. В противном случае сделать это будет невозможно,\
или крайне маловероятно из-за вычислительной сложности.\
Под интерактивностью протокола подразумевается непосредственный обмен информацией сторонами[1][2]. \
Таким образом, рассматриваемый протокол требует наличия интерактивных исходных данных (interactive input) \
от проверяющего, как правило, в виде задачи или проблемы. Цель легального доказывающего (имеющего доказательство) \
в этом протоколе — убедить проверяющего в том, что у него есть решение, не выдав при этом даже части «секретного» \
доказательства («нулевое разглашение»). Цель проверяющего же — это удостовериться в том, что доказывающая сторона \
«не лжёт»[2][3].\
Также были разработаны протоколы доказательства с нулевым разглашением[4][5], для которых не требовалось \
наличия интерактивных исходных данных, при этом доказательство которых, как правило, опирается на предположение об \
идеальной криптографической хеш-функции, то есть предполагается, что выход однонаправленной хеш-функции невозможно \
предсказать, если не известен её вход[6]'
In [ ]:
summarize(text, split= True)
In [ ]:
keywords(text, ratio=0.05, split=True)
In [ ]:
%%time
from gensim.corpora import Dictionary
from gensim.models import Phrases
# to create the bigrams
bigram_model = Phrases(texts)
import codecs
if 1 == 1:
with codecs.open('bigram_sentences_all.txt', 'w', encoding='utf_8') as f:
for unigram_sentence in texts:
bigram_sentence = u' '.join(bigram_model[unigram_sentence])
f.write(bigram_sentence + '\n')
from gensim.models.word2vec import LineSentence
#bigram_sentences = LineSentence('bigram_sentences_all.txt')
#bigram_sentences = open('bigram_sentences_all.txt', "r").read().splitlines()
import codecs
fileObj = codecs.open( 'bigram_sentences_all.txt', "r", "utf_8_sig" )
bigram_sentences = fileObj.read().splitlines() # или читайте по строке
fileObj.close()
trigram_model = Phrases(bigram_sentences)
triram_sentences = []
i =0
for bigram_sentence in bigram_sentences:
i += 1
triram_sentence = u' '.join(trigram_model[tokenize_only(bigram_sentence)])
triram_sentences.append(triram_sentence)
#if len(triram_sentences) != i:
#triram_sentence = u' '.join(' ')
print (i, len(triram_sentences))